import axios, { AxiosRequestHeaders, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { useUserStore } from "../store/user";
import { layer } from '@layui/layui-vue';
import router from '../router'

type TAxiosOption = {
    timeout: number;
    baseURL: string;
}
 
const config: TAxiosOption = {
    timeout: 5000,
    baseURL: "http://localhost:3000"
}
 
class Http {
    service;
    constructor(config: TAxiosOption) {
        this.service = axios.create(config)

        /* 请求拦截 */
        this.service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
            const userInfoStore = useUserStore();
            
            // 检查是否是不需要认证的接口
            const isPublicApi = config.url?.includes('/auth/login') || 
                               config.url?.includes('/auth/register') ||
                               config.url?.includes('/api/addresses') ||
                               config.url?.includes('/api/users');
            
            if (userInfoStore.token) {
                // 有token时，为所有请求添加Authorization头
                (config.headers as AxiosRequestHeaders).Authorization = `Bearer ${userInfoStore.token}`;
            } else if (!isPublicApi) {
                // 没有token且不是公开API时，跳转到登录页
                if(router.currentRoute.value.path !== '/login') {
                    router.push('/login');
                    return Promise.reject(new Error('需要登录'));
                }
            }
            
            return config
        }, error => {
            return Promise.reject(error);
        })

        /* 响应拦截 */
        this.service.interceptors.response.use((response: AxiosResponse<any>) => {
            // 处理后端API响应格式 (包含 code, message, data, timestamp)
            if (response.data.code !== undefined) {
                switch (response.data.code) {
                    case 200:
                        // 成功时返回完整的响应对象
                        return response.data;
                    case 500:
                        // 服务器错误
                        layer.msg(response.data.message || '服务器错误', { icon: 2 });
                        return Promise.reject(new Error(response.data.message || '服务器错误'));
                    case 99998:
                        // 会话超时
                        layer.confirm(
                        '会话超时, 请重新登录', 
                        { icon : 2, yes: function(){
                            router.push('/login');
                            layer.closeAll()
                        }});
                        return Promise.reject(new Error('会话超时'));
                    case 401:
                        // 未授权
                        layer.msg('未授权，请重新登录', { icon: 2 });
                        router.push('/login');
                        return Promise.reject(new Error('未授权'));
                    case 400:
                        // 请求参数错误
                        layer.msg(response.data.message || '请求参数错误', { icon: 2 });
                        return Promise.reject(new Error(response.data.message || '请求参数错误'));
                    default:
                        // 其他错误
                        layer.msg(response.data.message || '请求失败', { icon: 2 });
                        return Promise.reject(new Error(response.data.message || '请求失败'));
                }
            } else {
                // 兼容其他格式
                return response.data;
            }
        }, error => {
            return Promise.reject(error)
        })
    }

    /* GET 方法 */
    get<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.get(url, { params, ..._object })
    }
    /* POST 方法 */
    post<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.post(url, params, _object)
    }
    /* PUT 方法 */
    put<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.put(url, params, _object)
    }
    /* DELETE 方法 */
    delete<T>(url: string, params?: any, _object = {}): Promise<any> {
        return this.service.delete(url, { params, ..._object })
    }
    /* PATCH 方法 */
    patch<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.patch(url, params, _object)
    }
}

export default new Http(config)